package com.invengo.library_rfid.analyze.utils.uhf.formatHelp;

public class dm_barcode_fromlow {
    private String _error_message;
    private int _byte_length;
    private int _empty_bits_in_cur_byte;
    private int _cur_byte_index;
    private byte[] _bytes_value;

    public String get_error_message() {
        return _error_message;
    }

    public byte[] get_bytes_value() {
        return _bytes_value;
    }

    public dm_barcode_fromlow() {
        _byte_length = 8;
        _bytes_value = new byte[_byte_length];
        _empty_bits_in_cur_byte = 0;
        _cur_byte_index = 0;
    }

    public dm_barcode_fromlow(int bytelength) {
        _byte_length = bytelength;
        _bytes_value = new byte[bytelength];
        _empty_bits_in_cur_byte = 0;
        _cur_byte_index = 0;
    }

    public int add_long(long lvalue, int bits_space_count) {
        int used_bitslength_for_lvalue = 0;
        if (_empty_bits_in_cur_byte > 0) {
            if (_empty_bits_in_cur_byte >= bits_space_count) {
                _bytes_value[_cur_byte_index] += (byte)(lvalue << (8 - _empty_bits_in_cur_byte));
                _empty_bits_in_cur_byte -= bits_space_count;
                if (_empty_bits_in_cur_byte == 0) {
                    _cur_byte_index++;
                }
                return _cur_byte_index;
            }
            _bytes_value[_cur_byte_index] += (byte)(lvalue << (8 - _empty_bits_in_cur_byte));
            lvalue = lvalue >> _empty_bits_in_cur_byte;
            used_bitslength_for_lvalue = _empty_bits_in_cur_byte;
            _empty_bits_in_cur_byte = 0;
            _cur_byte_index++;
        }
        while (bits_space_count - used_bitslength_for_lvalue > 8) {
            _bytes_value[_cur_byte_index] += (byte)lvalue;
            lvalue = lvalue >> 8;
            used_bitslength_for_lvalue += 8;
            _cur_byte_index++;
        }
        if (bits_space_count - used_bitslength_for_lvalue > 0) {
            _bytes_value[_cur_byte_index] += (byte)lvalue;
            _empty_bits_in_cur_byte = 8 - (bits_space_count - used_bitslength_for_lvalue);
            if (_empty_bits_in_cur_byte == 0) {
                _cur_byte_index++;
            }
        }
        return _cur_byte_index;
    }

    public long get_long(int start_bits_position, int bits_length) {
        int geted_bit_count = 0;
        int pre_byte_position = start_bits_position % 8;
        int start_byte_index = start_bits_position / 8;
        long nResult = 0;
        if (pre_byte_position > 0) {
            if (bits_length <= 8 - pre_byte_position) {
                geted_bit_count = bits_length;
                byte bStep1 = (byte)(_bytes_value[start_byte_index] >> pre_byte_position);
                byte temp = (byte)(Math.pow(2, (double)bits_length) - 1);
                nResult = (long)(bStep1 & temp);
                return nResult;
            } else {
                geted_bit_count = 8 - pre_byte_position;
                byte bStep1 = (byte)(_bytes_value[start_byte_index] >> pre_byte_position);
                byte temp = (byte)(Math.pow(2, (double)(8 - pre_byte_position)) - 1);
                nResult = (long)(bStep1 & temp);
            }
            start_byte_index++;
        }
        while (bits_length - geted_bit_count >= 8) {
            nResult += (long)(((long)_bytes_value[start_byte_index]) << geted_bit_count);
            geted_bit_count += 8;
            start_byte_index++;
        }
        if (bits_length - geted_bit_count > 0) {
            byte temp = (byte)(Math.pow(2, (double)(bits_length - geted_bit_count)) - 1);
            nResult += (long)(((long)(_bytes_value[start_byte_index] & temp)) << geted_bit_count);
        }
        return nResult;
    }

    public int add_byte(byte bydata) {
        if (_cur_byte_index == _byte_length) {
            return 0;
        }
        if (_empty_bits_in_cur_byte == 0) {
            _bytes_value[_cur_byte_index] += bydata;
            _cur_byte_index++;
            return _cur_byte_index;
        } else {
            _bytes_value[_cur_byte_index] += (byte)(bydata << (8 - _empty_bits_in_cur_byte));
            _cur_byte_index++;
            if (_cur_byte_index == _byte_length) {
                return _cur_byte_index;
            }
            bydata = (byte)(bydata >> _empty_bits_in_cur_byte);
            _bytes_value[_cur_byte_index] += bydata;
            return _cur_byte_index;
        }
    }

    @Override
    public String toString() {
        String szTemp = "";
        for (int i = 0; i < _bytes_value.length; i++) {
            szTemp += String.format("%02X", _bytes_value[i]);
        }
        return szTemp;
    }

    public byte[] Encode_sjtu_96(String barcode) {
        String supper_barcode = barcode.toUpperCase();
        if (supper_barcode == null || supper_barcode.length() < 1 || supper_barcode.length() > 14) {
            _error_message = "条码号长度必须在1~14位之间!";
            return null;
        }
        for (int i = 0; i < 3; i++) {
            int tmp = (int)supper_barcode.charAt(i);
            if (tmp < 48 || tmp > 90 || (tmp > 57 && tmp < 65)) {
                _error_message = "条码号前3位不能包括字母或数字以外的字符!";
                return null;
            }
        }
        for (int i = 3; i < supper_barcode.length() - 2; i++) {
            int tmp = (int)supper_barcode.charAt(i);
            if (tmp < 48 || tmp > 57) {
                _error_message = "条码号第4位至倒数第2位之前，必须为纯数字!";
                return null;
            }
        }
        _byte_length = 8;
        _bytes_value = new byte[_byte_length];
        _empty_bits_in_cur_byte = 0;
        _cur_byte_index = 0;
        add_long(supper_barcode.length(), 4);
        if (supper_barcode.length() < 8) {
            add_long(0, 4);
            for (int i = 0; i < supper_barcode.length(); i++) {
                _bytes_value[_cur_byte_index] = (byte)supper_barcode.charAt(i);
                _cur_byte_index++;
            }
        } else {
            add_long((int)supper_barcode.charAt(supper_barcode.length() - 1), 8);
            for (int i = 2; i >= 0; i--) {
                int temp = (int)supper_barcode.charAt(i) - 0x30;
                add_long(temp, 6);
            }
            add_long((int)supper_barcode.charAt(3) - 0x30, 4);
            long numvalue = Long.parseLong(supper_barcode.substring(4, supper_barcode.length() - 1));
            add_long(numvalue, 30);
        }
        return _bytes_value;
    }

    public byte[] Encode_sjtu_128(String barcode) {
        String supper_barcode = barcode.toUpperCase();
        if (supper_barcode == null || supper_barcode.length() < 1 || supper_barcode.length() > 14) {
            _error_message = "条码号长度必须在1~14位之间!";
            return null;
        }
        for (int i = 0; i < supper_barcode.length() - 1; i++) {
            int tmp = (int)supper_barcode.charAt(i);
            if (tmp < 48 || tmp > 90 || (tmp > 57 && tmp < 65)) {
                _error_message = "条码号第1位至倒数第2位不能包括字母或数字以外的字符!";
                return null;
            }
        }
        _byte_length = 12;
        _bytes_value = new byte[_byte_length];
        _empty_bits_in_cur_byte = 0;
        _cur_byte_index = 0;
        add_long(supper_barcode.length(), 4);
        if (supper_barcode.length() < 12) {
            add_long(0, 4);
            for (int i = 0; i < supper_barcode.length(); i++) {
                _bytes_value[_cur_byte_index] = (byte)supper_barcode.charAt(i);
                _cur_byte_index++;
            }
        } else {
            add_long((int)supper_barcode.charAt(supper_barcode.length() - 1), 8);
            if (supper_barcode.length() == 14) {
                int temp = (int)supper_barcode.charAt(12) - 0x30;
                add_long(temp, 6);
                temp = (int)supper_barcode.charAt(11) - 0x30;
                add_long(temp, 6);
                temp = (int)supper_barcode.charAt(10) - 0x30;
                add_long(temp, 6);
            } else if (supper_barcode.length() == 13) {
                int temp = (int)supper_barcode.charAt(11) - 0x30;
                add_long(temp, 6);
                temp = (int)supper_barcode.charAt(10) - 0x30;
                add_long(temp, 6);
                add_long(0, 6);
            } else if (supper_barcode.length() == 12) {
                int temp = (int)supper_barcode.charAt(10) - 0x30;
                add_long(temp, 6);
                add_long(0, 6);
                add_long(0, 6);
            }
            add_long(0, 2);
            for (int i = 9; i >= 5; i--) {
                int temp = (int)supper_barcode.charAt(i) - 0x30;
                add_long(temp, 6);
            }
            add_long(0, 2);
            for (int i = 4; i >= 0; i--) {
                int temp = (int)supper_barcode.charAt(i) - 0x30;
                add_long(temp, 6);
            }
            add_long(0, 2);
        }
        return _bytes_value;
    }

    public String Decode_sjtu_96() {
        if (_bytes_value == null) {
            _error_message = "未压缩过条码，无法解码!";
            return "";
        }
        return Decode_sjtu_96(_bytes_value);
    }

    public String Decode_sjtu_128() {
        if (_bytes_value == null) {
            _error_message = "未压缩过条码，无法解码!";
            return "";
        }
        return Decode_sjtu_128(_bytes_value);
    }

    public String Decode_sjtu_96(byte[] bytevalue) {
        if (bytevalue.length != 8) {
            _error_message = "比特流传入小于8，不能解析!";
            return null;
        }
        byte[] tmpbyte = _bytes_value;
        _bytes_value = bytevalue;
        String barcode = "";
        int barcode_length = (int)get_long(0, 4);
        if (barcode_length < 8) {
            for (int i = 1; i < barcode_length + 1; i++) {
                barcode += (char)bytevalue[i];
            }
        } else {
            char cCRC = (char)get_long(4, 8);
            barcode = (char)(get_long(12, 6) + 0x30) + barcode;
            barcode = (char)(get_long(18, 6) + 0x30) + barcode;
            barcode = (char)(get_long(24, 6) + 0x30) + barcode;
            barcode += (char)(get_long(30, 4) + 0x30);
//            barcode += get_long(34, 30).toString().padLeft(barcode_length - 5, '0');
            barcode += padLeft(Long.toString(get_long(34, 30)),barcode_length-5,'0');
            barcode += cCRC;
        }
        _bytes_value = tmpbyte;
        return barcode;
    }


    /**
     * @作者 尧
     * @功能 String左对齐
     */
    public static String padLeft(String src, int len, char ch) {
        int diff = len - src.length();
        if (diff <= 0) {
            return src;
        }

        char[] charr = new char[len];
        System.arraycopy(src.toCharArray(), 0, charr, 0, src.length());
        for (int i = src.length(); i < len; i++) {
            charr[i] = ch;
        }
        return new String(charr);
    }


    public String Decode_sjtu_128(byte[] bytevalue) {
        if (bytevalue.length != 12) {
            _error_message = "比特流传入小于12，不能解析!";
            return null;
        }
        byte[] tmpbyte = _bytes_value;
        _bytes_value = bytevalue;
        String barcode = "";
        int barcode_length = (int)get_long(0, 4);
        if (barcode_length < 12) {
            for (int i = 1; i < barcode_length + 1; i++) {
                barcode += (char)bytevalue[i];
            }
        } else {
            char cCRC = (char)get_long(4, 8);
            barcode += (char)(get_long(12, 6) + 0x30);
            if (barcode_length > 12) {
                barcode = (char)(get_long(18, 6) + 0x30) + barcode;
            }
            if (barcode_length > 13) {
                barcode = (char)(get_long(24, 6) + 0x30) + barcode;
            }
            barcode += cCRC;
            String barcode2 = "";
            barcode2 = (char)(get_long(32, 6) + 0x30) + barcode2;
            barcode2 = (char)(get_long(38, 6) + 0x30) + barcode2;
            barcode2 = (char)(get_long(44, 6) + 0x30) + barcode2;
            barcode2 = (char)(get_long(50, 6) + 0x30) + barcode2;
            barcode2 = (char)(get_long(56, 6) + 0x30) + barcode2;
            String barcode3 = "";
            barcode3 = (char)(get_long(64, 6) + 0x30) + barcode3;
            barcode3 = (char)(get_long(70, 6) + 0x30) + barcode3;
            barcode3 = (char)(get_long(76, 6) + 0x30) + barcode3;
            barcode3 = (char)(get_long(82, 6) + 0x30) + barcode3;
            barcode3 = (char)(get_long(88, 6) + 0x30) + barcode3;
            barcode = barcode3 + barcode2 + barcode;
        }
        _bytes_value = tmpbyte;
        return barcode;
    }
}


